#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h> 


#include "gps_simulator.h"

GtkWidget *latitude_label;
GtkWidget *longitude_label;
GtkWidget *height_label;

GtkWidget *velocity_spinner;
GtkWidget *heading_spinner;
GtkWidget *pitch_spinner;
GtkWidget *latitude_spinner;
GtkWidget *longitude_spinner;
GtkWidget *height_spinner;
GtkWidget *updaterate_spinner;

void set_latitude_label(char * new_string)
{
	GDK_THREADS_ENTER(); 
	gtk_label_set_text(latitude_label, new_string);
	GDK_THREADS_LEAVE();
}

void set_longitude_label(char * new_string)
{
	GDK_THREADS_ENTER(); 
	gtk_label_set_text(longitude_label, new_string);
	GDK_THREADS_LEAVE();
}

void set_height_label(char * new_string)
{
	GDK_THREADS_ENTER(); 
	gtk_label_set_text(height_label, new_string);
	GDK_THREADS_LEAVE();
}

gint  get_velocity_spinner_value(void)
{
	return gtk_spin_button_get_value_as_int( velocity_spinner);
}

gint  get_heading_spinner_value(void)
{
	return gtk_spin_button_get_value_as_int( heading_spinner);
}

gint  get_pitch_spinner_value(void)
{
	return gtk_spin_button_get_value_as_int( pitch_spinner);
}

gdouble get_latitude_spinner_value(void)
{
	return gtk_spin_button_get_value_as_float( latitude_spinner);
}

gdouble get_longitude_spinner_value(void)
{
	return gtk_spin_button_get_value_as_float( longitude_spinner);
}

gint  get_height_spinner_value(void)
{
	return gtk_spin_button_get_value_as_int( height_spinner);
}

gint  get_updaterate_spinner_value(void)
{
	return gtk_spin_button_get_value_as_int( updaterate_spinner);
}

GtkWidget *buildGpsWidget(void)
{
	GtkWidget *vbox;

	GtkWidget *latitude_frame;
	GtkWidget *longitude_frame;
	GtkWidget *height_frame;

	vbox = gtk_vbox_new(FALSE, 0);

	latitude_frame =  gtk_frame_new ("Current Latitude");
	latitude_label = gtk_label_new ("NULL");
	gtk_container_add (GTK_CONTAINER (latitude_frame), latitude_label);
	gtk_box_pack_start (GTK_BOX (vbox), latitude_frame, FALSE, FALSE, 0);

	longitude_frame = gtk_frame_new ("Current Longitude");
	longitude_label = gtk_label_new ("NULL");
	gtk_container_add (GTK_CONTAINER (longitude_frame), longitude_label);
	gtk_box_pack_start (GTK_BOX (vbox), longitude_frame, FALSE, FALSE, 0);

	height_frame =  gtk_frame_new ("Current Height");
	height_label = gtk_label_new ("NULL");
	gtk_container_add (GTK_CONTAINER (height_frame), height_label);
	gtk_box_pack_start (GTK_BOX (vbox), height_frame, FALSE, FALSE, 0);

	return vbox;
}



GtkWidget *buildConfigWidget(void)
{
	GtkWidget *vbox;

	GtkWidget *velocity_frame;
	GtkWidget *velocity_adj;

	GtkWidget *heading_frame;
	GtkWidget *heading_adj;

	GtkWidget *pitch_adj;
	GtkWidget *pitch_frame;

	GtkWidget *latitude_adj;
	GtkWidget *latitude_frame;

	GtkWidget *longitude_adj;
	GtkWidget *longitude_frame;

	GtkWidget *height_adj;
	GtkWidget *height_frame;
	
	GtkWidget *updaterate_adj;
	GtkWidget *updaterate_frame;
	


	vbox = gtk_vbox_new(FALSE, 0);

	velocity_frame = gtk_frame_new ("Velocity");	
	velocity_adj = gtk_adjustment_new(1,0,10000,.1,1,1);      
	velocity_spinner = gtk_spin_button_new (velocity_adj, 0, 1);
	gtk_container_add (GTK_CONTAINER (velocity_frame), velocity_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), velocity_frame, FALSE, FALSE, 0);

	heading_frame = gtk_frame_new ("Heading");	
	heading_adj = gtk_adjustment_new(90,0,359,1,1,1);      
	heading_spinner = gtk_spin_button_new (heading_adj, 0, 0);
	gtk_container_add (GTK_CONTAINER (heading_frame), heading_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), heading_frame, FALSE, FALSE, 0);

	pitch_frame = gtk_frame_new ("Pitch");	
	pitch_adj = gtk_adjustment_new(0,-90,90,1,1,1);      
	pitch_spinner = gtk_spin_button_new (pitch_adj, 0, 0);
	gtk_container_add (GTK_CONTAINER (pitch_frame), pitch_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), pitch_frame, FALSE, FALSE, 0);

	latitude_frame = gtk_frame_new ("Starting Latitude");	
	latitude_adj = gtk_adjustment_new(34.419868,-360,360,.0001,1,1);      
	latitude_spinner = gtk_spin_button_new (latitude_adj, 0, 4);                               
	gtk_container_add (GTK_CONTAINER (latitude_frame), latitude_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), latitude_frame, FALSE, FALSE, 0);

	longitude_frame = gtk_frame_new ("Starting Longitude");	
	longitude_adj = gtk_adjustment_new(-119.693513,-360,360,.0001,1,1);      
	longitude_spinner = gtk_spin_button_new (longitude_adj, 0, 4);                               
	gtk_container_add (GTK_CONTAINER (longitude_frame), longitude_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), longitude_frame, FALSE, FALSE, 0);

	height_frame = gtk_frame_new ("Starting Height");	
	height_adj = gtk_adjustment_new(100,-10000,32000,.01,1,1);      
	height_spinner = gtk_spin_button_new (height_adj, 0, 3);                               
	gtk_container_add (GTK_CONTAINER (height_frame), height_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), height_frame, FALSE, FALSE, 0);
	
	updaterate_frame = gtk_frame_new ("Update Rate");	
	updaterate_adj = gtk_adjustment_new(1,0,100,1,1,1);      
	updaterate_spinner = gtk_spin_button_new (updaterate_adj, 0, 0);                               
	gtk_container_add (GTK_CONTAINER (updaterate_frame), updaterate_spinner);
	gtk_box_pack_start (GTK_BOX (vbox), updaterate_frame, FALSE, FALSE, 0);

	return vbox;
}


GtkWidget *buildMenuBar(void)
{
	GtkWidget *vbox;

	GtkWidget *menubar;
	GtkWidget *filemenu;
	GtkWidget *file;
	GtkWidget *quit;       

	vbox = gtk_vbox_new(FALSE, 0);

	menubar = gtk_menu_bar_new();
	filemenu = gtk_menu_new();

	file = gtk_menu_item_new_with_label("File");
	quit = gtk_menu_item_new_with_label("Quit");
	gtk_signal_connect(GTK_OBJECT(quit), "activate",GTK_SIGNAL_FUNC(gtk_main_quit), NULL);

	gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu);
	gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit);
	gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file);
	gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3);

	return vbox;
}


void update_ui(void)
{
	char buffer[50];

	sprintf(buffer,"%lf", get_latitude_as_float());
	set_latitude_label(buffer);                      

	sprintf(buffer,"%lf", get_longitude_as_float());
	set_longitude_label(buffer);

	sprintf(buffer,"%lf", get_height_as_float());
	set_height_label(buffer);
}

void timeoutcallback(gpointer data)
{ 
	set_mm_per_second(get_velocity_spinner_value()*1000);
	set_heading_direction(get_heading_spinner_value());
	set_pitch_direction(get_pitch_spinner_value());
	set_message_per_second(get_updaterate_spinner_value());
	run_gps_simulator_loop();
	update_ui();
}
void pitchcallback(GtkWidget *widget, gpointer label)
{
	gtk_spin_button_set_value(pitch_spinner,0);
}

void buttoncallback(GtkWidget *widget, gpointer label)
{
	static gint func_ref;   
	static int running_state = 0;
	static int last_updaterate= 0;

	char buffer[50];
	

	
	if(running_state == 0)
	{
		gtk_label_set_text(label, "Running");

		set_latitude_as_float(get_latitude_spinner_value());
		set_longitude_as_float(get_longitude_spinner_value());
		set_height_as_float(get_height_spinner_value());
		set_mm_per_second(get_velocity_spinner_value()*1000);
		set_heading_direction(get_heading_spinner_value());
		set_pitch_direction(get_pitch_spinner_value());

		update_ui();

		//start a 1 second timeout
		func_ref = g_timeout_add (1000/get_updaterate_spinner_value(), timeoutcallback, NULL);
		running_state = 1;
	}
	else
	{
		gtk_label_set_text(label, "Stopped");

		//stop the 1 secound timeout
		g_source_remove (func_ref);
		running_state = 0;
	}

}


static gboolean on_key_press (GtkWidget *widget, GdkEventKey *event)
{
	guint modifiers;

	modifiers = gtk_accelerator_get_default_mod_mask ();

	//if (event->keyval == GDK_F10 && (event->state & modifiers) == GDK_CONTROL_MASK)


	switch (event->keyval)
	{
		case GDK_a:
		case GDK_A:
			if(get_heading_spinner_value() == 0)
			{
				gtk_spin_button_set_value(heading_spinner,359);
			}
			else
			{
				gtk_spin_button_spin(heading_spinner,1,1);
			}
			break;
		case GDK_D:
		case GDK_d:
			if(get_heading_spinner_value() == 359)
			{
				gtk_spin_button_set_value(heading_spinner,0);
			}
			else
			{
				gtk_spin_button_spin(heading_spinner,0,1);
			}
			break;
		case GDK_W:
		case GDK_w:
			gtk_spin_button_spin(pitch_spinner,1,1);
			break;
		case GDK_S:
		case GDK_s:
			gtk_spin_button_spin(pitch_spinner,0,1);
			break; 
		case GDK_equal:	    
		case GDK_plus:
				gtk_spin_button_spin(velocity_spinner,0,1);
			break; 
		case GDK_minus:
				gtk_spin_button_spin(velocity_spinner,1,1);
			break;   


		case GDK_Left:
			//set_longitude(get_longitude()-1e7);
			break;
		case GDK_Right:
			//set_longitude(get_longitude()+1e7);
			break;
		case GDK_Up:
			//set_latitude(get_latitude()+1e7);
			break;
		case GDK_Down:
			//set_latitude(get_latitude()-1e7);
			break;   
		default:
			return FALSE; // propogate event 
	} 


	return TRUE;
}

int main (int argc, char *argv[])
{


	GtkWidget *window;
	GtkWidget *vbox;

	GtkWidget *mainframe;
	GtkWidget *label;
	GtkWidget *startbutton;
	GtkWidget *dummybutton;

	GTimer  *timer;



	gtk_init (&argc, &argv);

	/* create the main, top level, window */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

	/* give it the title */
	gtk_window_set_title (GTK_WINDOW (window), "GPS Simulator");
	gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);

	mainframe = gtk_vbox_new(TRUE, 1);
	gtk_container_add(GTK_CONTAINER(window), mainframe);

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(mainframe), vbox);



	//menu bar
	gtk_container_add (GTK_CONTAINER (vbox), buildMenuBar());



	//lat long stuff
	gtk_container_add (GTK_CONTAINER (vbox), buildGpsWidget());



	//spinner test


	gtk_container_add (GTK_CONTAINER (vbox), buildConfigWidget());        


	//start button
	label = gtk_label_new ("Stopped");
	gtk_container_add (GTK_CONTAINER (vbox), label);
	gtk_widget_show (label);

	startbutton = gtk_button_new_with_label("Start/Stop");
	gtk_container_add (GTK_CONTAINER (vbox), startbutton);
	gtk_widget_show (startbutton);
	gtk_signal_connect(startbutton, "clicked", GTK_SIGNAL_FUNC(buttoncallback), label);


	dummybutton = gtk_button_new_with_label("Reset Pitch");
	gtk_container_add (GTK_CONTAINER (vbox), dummybutton);
	gtk_widget_show (dummybutton);
	gtk_signal_connect(dummybutton, "clicked", GTK_SIGNAL_FUNC(pitchcallback), label);

	//a timer 

	timer = g_timer_new();
	g_timer_start(timer);

	//a key 
	gtk_signal_connect ( window, "key_press_event", GTK_SIGNAL_FUNC (on_key_press), NULL); 




	gtk_widget_show_all (window);
	gtk_main ();
	return 0;
}

